﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MemoryViewControl;

namespace MemoryView
{
  public partial class FormMain : Form
  {
    private byte[] data = new byte[32 * 1024];
    private ushort[] data16 = new ushort[32 * 1024];
    private bool changeCools = true;
    private bool changeClearsChanged = true;

    private Random rand = new Random();

    public FormMain()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      rand.NextBytes(data);
      memoryViewControl1.MemorySpace.AddressBits = 16;
      memoryViewControl1.MemorySpace.MapRange(64, (uint)((data.Length / 2) - 64), null, 8);
      memoryViewControl1.MemorySpace.UpdateMemory(64, data, (uint)(data.Length / 2) - 64, false);

      const bool test16bits = false;

      if (!test16bits)
      {
        memoryViewControl1.MemorySpace.MapRange(0x8000, (uint)data.Length / 2, null, 8);
        memoryViewControl1.MemorySpace.UpdateMemory(0x8000, data, (uint)(data.Length / 2), false);
      }
      else
      {
        for (int i = 0; i < data16.Length; ++i)
        {
          data16[i] = (ushort)rand.Next(ushort.MaxValue);
        }
        memoryViewControl1.MemorySpace.MapRange(0x8000, (uint)data.Length, null, 8);
        memoryViewControl1.MemorySpace.UpdateMemory(0x8000, data16, (uint)data.LongLength, false);
      }
      memoryViewControl1.MemorySpace.SetMemoryDirty(0, 0x100);
    }

    private void toolStripButtonChangeMemory_Click(object sender, EventArgs e)
    {
      UpdateMemory();
    }

    private void UpdateMemory()
    {
      if (changeCools)
        memoryViewControl1.MemorySpace.Cool(0.95f);

      if (changeClearsChanged)
        memoryViewControl1.MemorySpace.ClearChanged();

      const int totalMemory = 0x10000;
      const int minChange = 128;
      const int blockSize = 1;

      for (int i = 0; i < 20; ++i)
      {
        uint address = (uint)rand.Next((totalMemory - minChange) / blockSize) * blockSize;
        uint length = (uint)(rand.Next((int)Math.Min((totalMemory - address - minChange) / blockSize, 16)) * blockSize);

        rand.NextBytes(data);
        memoryViewControl1.MemorySpace.UpdateMemory(address, data, length, true);
      }

      for (int i = 0; i < 20; ++i)
      {
        uint address = (uint)rand.Next((totalMemory - minChange) / blockSize) * blockSize;
        uint length = (uint)(rand.Next((int)Math.Min((totalMemory - address - minChange) / blockSize, 16)) * blockSize);

        memoryViewControl1.MemorySpace.UpdateRead(address, length);
      }
      
      for (int i = 0; i < 2; ++i)
      {
        uint address = (uint)rand.Next((totalMemory - minChange) / blockSize) * blockSize;
        uint length = (uint)(rand.Next((int)Math.Min((totalMemory - address - minChange) / blockSize, 16)) * blockSize);

        int highlight = rand.Next(16);
        memoryViewControl1.MemorySpace.SetHighlight(address, length, highlight);
      }

      for (int i = 0; i < 128; ++i)
      {
        uint address = (uint)rand.Next((totalMemory - minChange) / blockSize) * blockSize;
        uint length = (uint)(rand.Next((int)Math.Min((totalMemory - address - minChange) / blockSize, 16)) * blockSize);

        int hidden = 1;// rand.Next(16);
        memoryViewControl1.MemorySpace.SetHidden(address, length, hidden != 0);
      }
      
      //memoryViewControl1.SetHighlightBrush(1, new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.DiagonalBrick, memoryViewControl1.BackColor, Color.CornflowerBlue));
      //memoryViewControl1.SetHighlightBrush(2, new System.Drawing.Drawing2D.LinearGradientBrush(Point.Empty, new Point(30, 30), memoryViewControl1.BackColor, Color.CornflowerBlue));

      const int minChangeBank = 128;
      const int blockSizeBank = 256;

      for (int i = 0; i < 1; ++i)
      {
        if (rand.Next(10) != 0)
          continue;

        uint address = (uint)rand.Next((totalMemory - minChangeBank) / blockSizeBank) * blockSizeBank;
        uint length = (uint)(rand.Next((int)Math.Min((totalMemory - address - minChangeBank) / blockSizeBank, 16)) * blockSizeBank);

        memoryViewControl1.MemorySpace.UpdateBank(address, length);
      }
    }

    private void toolStripButtonClearChanged_Click(object sender, EventArgs e)
    {
      memoryViewControl1.MemorySpace.ClearChanged();
    }

    private void toolStripButtonMakeDirty_Click(object sender, EventArgs e)
    {
      memoryViewControl1.MemorySpace.SetDirty();
    }

    private void toolStripButtonCool_Click(object sender, EventArgs e)
    {
      memoryViewControl1.MemorySpace.Cool(0.75f);
    }

    private void toolStripButtonChangeCools_Click(object sender, EventArgs e)
    {
      changeCools = toolStripButtonChangeCools.Checked;
    }

    private void toolStripButtonClearsChanged_Click(object sender, EventArgs e)
    {
      changeClearsChanged = toolStripButtonClearsChanged.Checked;
    }

    private void toolStripButtonLiveUpdate_Click(object sender, EventArgs e)
    {
      timerUpdate.Enabled = toolStripButtonLiveUpdate.Checked;
    }

    private void timerUpdate_Tick(object sender, EventArgs e)
    {
      UpdateMemory();
    }
  }
}
